package sasl

// A Mechanism is a particular way of authenticating over SASL. Common
// mechanisms include plaintext login+password, Kerberos, and OpenID.
type Mechanism interface {
	// Registered name of the mechanism.
	Name() string
	// True if the mechanism starts with a client message.
	ClientInitiated() bool
	// Start a client-side SASL exchange for this mechanism. Returns
	// the first message to send to the server, and the state machine
	// to further the exchange.
	Client() MechanismClientState
	// Free any persistent resources associated with this mechanism.
	Close() error
}

type MechanismClientState interface {
	// Respond to the next peer challenge payload. Return a non-nil
	// error to abort the exchange.
	Next(challenge []byte) (response []byte, err error)
	// Free any resources in use.
	Close() error
}

// The EXTERNAL mechanism.
type external struct{}

func MechExternal() Mechanism {
	return external{}
}

func (e external) Name() string {
	return "EXTERNAL"
}

func (e external) ClientInitiated() bool {
	return true
}

func (e external) Client() MechanismClientState {
	return e
}

func (e external) Next([]byte) ([]byte, error) {
	return []byte{}, nil
}

func (e external) Close() error {
	return nil
}
